# -*- coding: utf-8 -*-
from requests import *
from snownlp import SnowNLP, summary
from api import *
import random
import time
import re
import yaml
import json

class AiReply():
    def __init__(self, sid=400000, name='', response='', prefix='', suffix='', standard=500):
        self.id = sid
        self.info = self.getInfo()
        self.name = name
        self.response = response
        self.test = 0
        self.prefix = prefix
        self.suffix = suffix
        self.standard = standard
        self.api = CodemaoApi()
        file = open('.dict', 'r')
        self.replies = eval(file.read())
        file.close()
        # self.replies = {
        #     '1': ['没事没事awa', '唉，都这样', '不要悲伤，不要心急，忧郁的日子总会过去[doge]', 
        #           '（安慰安慰QwQ', '虽然我只是Albert的AI算法，没有感情，但这似乎是个悲伤的故事T_T',
        #           '没事的，要坚定啊', '别难过啊，找到解决方法是最重要滴',
        #           '别生气，别着急，气出病来谁得意[doge]', '加油鸭！！', 
        #           '根据我的算法分析，你的情绪似乎不太好呢awa'],
        #     '2': ['你也来了啊，少年', '啊这', '不错不错', '一起努力！！', 
        #           '---------正道的光--------', '根据我的算法分析，你的情绪很一般呢awa',
        #           '虽然我只是Albert的AI算法，没有感情，但我还是觉得我能理解你的心情',
        #           '振奋一下qwq 年前就要醒着拼 [doge]', '(但愿人没事[doge]'],
        #     '3': ['偶买噶？', '啊这、、、', '元芳，你怎么看', '发生了什么[doge]',
        #           '有点意思[手动滑稽]', '呦呵~awa', '（）作为一套算法，我对此事不发表见解[doge]',
        #           '阿巴阿巴阿巴）））让我好好李姐下', '根据我的算法分析，你的情绪很平常呢awa',
        #           '不错不错，真不戳，一起加油！！！', 'Albert的AI到此一游~~',
        #           '如果你无聊，可以和Albert聊聊天哦QwQ', '共勉一下~~~'],
        #     '4': ['兴奋~~~~~~', '容我搓手手、、、', '根据我的算法分析，你的情绪很不错呢awa',
        #           '本AI和你一样激动！！！！', '很不错啊，代码借我学习下~~（流汗黄豆.jpg', 
        #           '稍等，我还要向我的主人传达你的激动~~[doge]', 'Albert的AI到此一游~~不喜勿喷~~',
        #           '向前进，向前进，革命意志可不阻挡~~~~~[doge]'],
        #     '5': ['wow~~~~~', '！！！！！！！！！（激动到语无伦次',
        #           '根据我的算法分析，你的情绪很激动呢awa', '加油加油，本AI与你共勉QwQ',
        #           '我的词库已经不足以表达看到这个帖子的兴奋了，赶紧找Albert再教我些~~~']
        # }

    def login(self, id, password):
        info = self.api.login(id, password)
        if info.get('error_number'):
            raise RuntimeError('无法登录')

    def getInfo(self, key=None):
        with open('.info', 'r') as f:
            info = json.load(f)
            return info[key] if key else info

    def setInfo(self, key, value):
        with open('.info', 'r+') as f:
            info = json.load(f)
            info[key] = value
            f.seek(0)
            json.dump(info, f)
            return info
    
    def getReply(self, content):
        if content:
            s = SnowNLP(content)
            sentences = s.sentences
            sentiment = 0
            for i in sentences:
                sentiment += SnowNLP(i).sentiments
            sentiment /= len(sentences)
            
            if 0 <= sentiment < 0.2:
                answer = random.choice(self.replies['1'])
            elif 0.2 <= sentiment < 0.4:
                answer = random.choice(self.replies['2'])
            elif 0.4 <= sentiment < 0.6:
                answer = random.choice(self.replies['3'])
            elif 0.6 <= sentiment < 0.8:
                answer = random.choice(self.replies['4'])
            elif 0.8 <= sentiment <= 1.0:
                answer = random.choice(self.replies['5'])
        else:
            answer = '我瞅瞅~~~'
        return answer

    def run(self):
        # 多轮询算法
        while True:
            # 读取回复消息
            message = self.api.getMessage('COMMENT_REPLY', 20)['items']
            for m in message:
                if m['read_status'] == 'UNREAD':
                    content = json.loads(m['content'])
                    if content['message']['business_id'] not in self.info['uald-article'] and content['message']['replied'] and content['message']['replied'].startswith(f'【{self.name}智能回复】'):
                        self.sendL2Reply(content)
                else:
                    break
            # 获取最新文章
            details = get(f'https://api.codemao.cn/web/forums/posts/{self.id}/details')
            if details.status_code != 404:
                self.id += 1
                self.test = 0
                self.sendReply(details.json())
                time.sleep(5)
            else:
                if self.test == 5:
                    self.id -= 5
                    self.test = 0
                else:
                    self.test += 1
                    self.id += 1
                time.sleep(0.5)

    def sendReply(self, details):
        if '@' + self.name in details['title'] or '@' + self.name in details['content']:
            # 回复聊天
            reply = f'<p><p>【{self.name}智能回复】' + self.response + '</p>\
                    <p>目前支持以下功能：/用户信息/ /作品点赞/ /AI聊天/ /关闭回复/</p> \
                    <p>在这一回帖下回复对应功能代号即可~~在帖子中或标题中@我就可以召唤哦~~</p></p>'
            info = self.api.postReply(details['id'], reply)
            if info.get('error_code') == 'Limit-Operation@Ratelimit':
                print('操作过于频繁，正在保持等待...')
                time.sleep(10)
                info = self.api.postReply(details['id'], reply)
            elif info.get('error_code') == 'Restricted-Operation@Ratelimit':
                raise RuntimeError('操作过于频繁，24小时后再试')
        else:
            # 智能回复
            content = re.sub('<\/?.+?\/?>', '', details['content']).strip()
            reply = self.prefix + self.getReply(content) + self.suffix
            info = self.api.postReply(details['id'], reply)
            if info.get('error_code') == 'Limit-Operation@Ratelimit':
                print('操作过于频繁，正在保持等待...')
                time.sleep(10)
                info = self.api.postReply(details['id'], reply)
            elif info.get('error_code') == 'Restricted-Operation@Ratelimit':
                raise RuntimeError('操作过于频繁，24小时后再试')
            quality = self.judgeQuality(content)
            if quality > self.standard:
                self.api.follow(details['user']['id'])
            print(details['id'], reply, quality)

    def judgeQuality(self, content):
        quality = len(content) * 0.15 * random.randint(1, 10)
        return quality

    def sendL2Reply(self, content):
        msg = content['message']['reply']
        if '/用户信息/' in msg:
            reply = f'【{self.name}智能回复】用户id？(可获得性别、头像等隐藏信息哦~)(格式：用户+*用户id*)'
        elif '/作品点赞/' in msg:
            reply = f'【{self.name}智能回复】作品id？(格式：作品+*作品id*)'
        elif '/AI聊天/' in msg:
            reply = '正在开发中~'
            # reply = '已开启AI聊天，回复/停止聊天/即可关闭~'
        elif '/关闭回复/' in msg:
            value = self.getInfo('uald-article')
            value.append(content['message']['business_id'])
            self.info = self.setInfo('uald-article',  value)
            reply = '已关闭回复~'
        elif msg.startswith('用户'):
            urid = msg.strip().strip('用户')
            try:
                info = self.api.getUserInfo(urid)
                reply = f'用户名：{info["data"]["userInfo"]["user"]["nickname"]}； \
                        性别：{"男" if info["data"]["userInfo"]["user"]["sex"] else "女"}； \
                        个新签名: {info["data"]["userInfo"]["user"]["description"]}； \
                        头像网址：{info["data"]["userInfo"]["user"]["avatar"]}'
            except:
                reply = '获取失败，该用户不存在~'
        elif msg.startswith('作品'):
            wkid = msg.strip().strip('作品')
            try:
                info = self.api.likeWork(wkid)
                reply = '已点赞~'
            except:
                reply = '请求失败，该作品不存在~'
        else:
            reply = '暂时不能理解您~'
        info = self.api.postL2Reply(content['message']['replied_id'], content['message']['reply_id'], reply)
        print(info)
        if info.get('error_code') == 'Limit-Operation@Ratelimit':
            print('操作过于频繁，正在保持等待...')
            time.sleep(10)
            info = self.api.postL2Reply(content['message']['replied_id'], content['message']['reply_id'], content['message']['reply_id'], reply)
        elif info.get('error_code') == 'Restricted-Operation@Ratelimit':
            raise RuntimeError('操作过于频繁，24小时后再试')
        print(msg, reply)


def customize():
    if os.path.exists('config.yml'):
        with open('config.yml') as f:
            info = yaml.load(f, yaml.Loader)
    else:
        raise ValueError('The file config.yml is required.')
    return info


if __name__ == '__main__':
    info = customize()
    engine = AiReply(int(info['ai']['sid']), info['ai']['name'], 
                     info['ai']['response'], info['ai']['prefix'],
                     info['ai']['suffix'], int(info['ai']['standard']))
    engine.login(info['user']['id'], info['user']['password'])
    engine.run()
